/**
 * 消息选择管理 Composable
 * 处理消息的选中状态和批量操作
 * @author LYC
 * @date 2025-09-13
 */

import { computed, reactive, readonly } from 'vue'
import type { Message } from '@/store/chat/type'

export interface MessageSelectionState {
  selectedMessageIds: Set<string>
  isMultiSelectMode: boolean
  lastSelectedMessageId: string | null
}

/**
 * 消息选择管理 Hook
 */
export function useMessageSelection() {
  // 选择状态
  const state = reactive<MessageSelectionState>({
    selectedMessageIds: new Set(),
    isMultiSelectMode: false,
    lastSelectedMessageId: null
  })

  // 计算属性
  const selectedCount = computed(() => state.selectedMessageIds.size)
  const hasSelectedMessages = computed(() => selectedCount.value > 0)
  const selectedMessageIds = computed(() => Array.from(state.selectedMessageIds))

  /**
   * 检查消息是否被选中
   */
  const isMessageSelected = (messageId: string): boolean => {
    return state.selectedMessageIds.has(messageId)
  }

  /**
   * 选中单个消息
   */
  const selectMessage = (messageId: string): void => {
    state.selectedMessageIds.add(messageId)
    state.lastSelectedMessageId = messageId
  }

  /**
   * 取消选中单个消息
   */
  const unselectMessage = (messageId: string): void => {
    state.selectedMessageIds.delete(messageId)
    if (state.lastSelectedMessageId === messageId) {
      state.lastSelectedMessageId = null
    }
  }

  /**
   * 切换消息选中状态
   */
  const toggleMessageSelection = (messageId: string): void => {
    if (isMessageSelected(messageId)) {
      unselectMessage(messageId)
    } else {
      selectMessage(messageId)
    }
  }

  /**
   * 选中多个消息（范围选择）
   */
  const selectMessageRange = (messages: Message[], startId: string, endId: string): void => {
    const startIndex = messages.findIndex((m) => m.id === startId)
    const endIndex = messages.findIndex((m) => m.id === endId)

    if (startIndex === -1 || endIndex === -1) return

    const minIndex = Math.min(startIndex, endIndex)
    const maxIndex = Math.max(startIndex, endIndex)

    for (let i = minIndex; i <= maxIndex; i++) {
      selectMessage(messages[i].id)
    }
  }

  /**
   * 选中所有消息
   */
  const selectAllMessages = (messages: Message[]): void => {
    messages.forEach((message) => selectMessage(message.id))
  }

  /**
   * 清空选择
   */
  const clearSelection = (): void => {
    state.selectedMessageIds.clear()
    state.lastSelectedMessageId = null
  }

  /**
   * 进入多选模式
   */
  const enterMultiSelectMode = (initialMessageId?: string): void => {
    state.isMultiSelectMode = true
    if (initialMessageId) {
      selectMessage(initialMessageId)
    }
  }

  /**
   * 退出多选模式
   */
  const exitMultiSelectMode = (): void => {
    state.isMultiSelectMode = false
    clearSelection()
  }

  /**
   * 处理消息点击（支持Ctrl/Shift选择）
   */
  const handleMessageClick = (messageId: string, messages: Message[], event: MouseEvent): void => {
    if (!state.isMultiSelectMode) return

    if (event.ctrlKey || event.metaKey) {
      // Ctrl/Cmd + 点击：切换选中状态
      toggleMessageSelection(messageId)
    } else if (event.shiftKey && state.lastSelectedMessageId) {
      // Shift + 点击：范围选择
      selectMessageRange(messages, state.lastSelectedMessageId, messageId)
    } else {
      // 普通点击：直接切换当前消息的选中状态，不清空其他选择
      toggleMessageSelection(messageId)
    }
  }

  /**
   * 获取选中的消息对象
   */
  const getSelectedMessages = (messages: Message[]): Message[] => {
    return messages.filter((message) => isMessageSelected(message.id))
  }

  return {
    // 状态
    state: readonly(state),
    selectedCount,
    hasSelectedMessages,
    selectedMessageIds,

    // 方法
    isMessageSelected,
    selectMessage,
    unselectMessage,
    toggleMessageSelection,
    selectMessageRange,
    selectAllMessages,
    clearSelection,
    enterMultiSelectMode,
    exitMultiSelectMode,
    handleMessageClick,
    getSelectedMessages
  }
}

/**
 * 全局消息选择管理
 * 在整个聊天组件中共享选择状态
 */
let globalMessageSelection: ReturnType<typeof useMessageSelection> | null = null

export function useGlobalMessageSelection(): ReturnType<typeof useMessageSelection> {
  if (!globalMessageSelection) {
    globalMessageSelection = useMessageSelection()
  }
  return globalMessageSelection
}
